import re

def parse_vocaloid_songbox(wikitext):
    """使用正则表达式解析 MediaWiki 文本"""
    result = {}
    
    # 1. 提取歌曲信息框
    songbox_match = re.search(r'\{\{VOCALOID_Songbox([\s\S]*?)\}\}', wikitext)
    if songbox_match:
        songbox_content = songbox_match.group(1)
        #print(songbox_content)
        result['songbox'] = {
            'title': extract_param(songbox_content, '歌曲名称'),
            'singers': extract_param(songbox_content, '演唱'),
            'uploader': extract_param(songbox_content, 'UP主'),
            'links': extract_param(songbox_content, '链接'),
            'other_info': extract_param(songbox_content, '其他资料'),
            'bb_id': extract_param(songbox_content, 'bb_id'),
            'upload_time': extract_param(songbox_content, '投稿时间'),
            'img_info': extract_param(songbox_content, '图片信息'),
        }
    return result
def extract_param(content, param_name):
    """从模板内容中提取参数值"""
    pattern = rf'\|{re.escape(param_name)}\s*=\s*(.*?)\s*(?=\n\||\n}}\}}|\||$)'
    match = re.search(pattern, content, re.DOTALL)
    return match.group(1).strip() if match else None

def extract_introduction(text):
    """
    从MediaWiki文本中提取简介部分
    :param text: MediaWiki格式的文本
    :return: 提取的简介内容
    """
    # 使用正则表达式匹配简介部分
    pattern = r'==\s*简介\s*==\n(.*?)(?=\n==|$)'
    match = re.search(pattern, text, re.DOTALL)
    
    if match:
        res = match.group(1).strip()
        
        # 改进的bilibiliCount移除模式
        # 使用非贪婪匹配处理嵌套模板
        bili_pattern = r'，?截至(?:現在|现在)已有\{\{[Bb]ilibiliCount.*?\}\}次观看，\{\{[Bb]ilibiliCount.*?\}\}人收藏[。]?'
        res = re.sub(bili_pattern, '', res, flags=re.DOTALL)
        
        # 移除所有模板（包括嵌套的）
        template_pattern = r'\{\{.*?\}\}'
        res = re.sub(template_pattern, '', res, flags=re.DOTALL)
        
        # 清理维基标记
        res = re.sub(r'\[\[|\]\]', '', res)
        res = re.sub(r'\'\'', '', res)  # 处理粗体标记
        
        # 移除多余空格和空行
        res = re.sub(r' +', ' ', res)
        res = re.sub(r'\n{3,}', '\n\n', res).strip()
        
        return res
    return None


def parse_music_section(text):
    # 定义正则表达式匹配模式
    section_pattern = r'(?:^==\s*歌曲\s*==\n)(.*?)(?=^==|\Z)'
    entry_pattern = r'^;([^\n]+)\n(.*?)(?=^;|\Z)'
    bili_pattern = r'\{\{BilibiliVideo\|id=([^}]+)\}\}'
    music163_pattern = r'\{\{Music163\|id=([^}]+)\}\}'
    
    # 解析结果列表
    results = []
    
    # 分割不同的歌曲部分
    sections = []
    for match in re.finditer(section_pattern, text, re.DOTALL | re.MULTILINE):
        sections.append(match.group(1))
    
    for section in sections:
        # 解析每个部分中的条目（有标题的情况）
        entries = []
        for entry_match in re.finditer(entry_pattern, section, re.DOTALL | re.MULTILINE):
            entries.append((entry_match.group(1), entry_match.group(2)))
        
        # 处理有标题的条目
        for title, content in entries:
            # 处理标题中的繁简体转换
            normalized_title = title.replace("聲", "声").replace("製", "制")
            
            # 解析BilibiliVideo
            for bili_match in re.finditer(bili_pattern, content):
                video_id = bili_match.group(1)
                if video_id.isdigit():
                    results.append(f"{normalized_title}的av号是av{video_id}")
                else:
                    results.append(f"{normalized_title}的BV号是{video_id}")
            
            # 解析Music163
            for music_match in re.finditer(music163_pattern, content):
                music_id = music_match.group(1)
                results.append(f"{normalized_title}的网易云id是{music_id}")
        
        # 处理无标题的条目（直接放置模板的情况）
        # 检查整个部分中是否还有未处理的模板
        # 有标题条目已处理的内容范围
        covered_content = "".join(content for _, content in entries)
        
        # 找出整个部分中未覆盖的内容
        uncovered_content = section
        for _, content in entries:
            uncovered_content = uncovered_content.replace(content, "", 1)
        
        # 解析未覆盖内容中的模板
        if uncovered_content.strip():
            # 解析BilibiliVideo
            for bili_match in re.finditer(bili_pattern, uncovered_content):
                video_id = bili_match.group(1)
                if video_id.isdigit():
                    results.append(f"歌曲的av号是av{video_id}")
                else:
                    results.append(f"歌曲的BV号是{video_id}")
            
            # 解析Music163
            for music_match in re.finditer(music163_pattern, uncovered_content):
                music_id = music_match.group(1)
                results.append(f"歌曲的网易云id是{music_id}")
    
    return results


def parse_lyrics_section(text):
    """
    解析歌词章节内容，提取制作人员信息和歌词
    
    Args:
        text (str): 包含歌词章节的完整文本
    
    Returns:
        dict: 包含staff和lyrics的字典
    """
    # 改进1：更灵活的章节匹配（允许章节后空行）
    section_pattern = r'==\s*歌词\s*==\n+(.*?)(?=\n==|\Z)'
    section_match = re.search(section_pattern, text, re.DOTALL)
    
    if not section_match:
        return {"staff": {}, "lyrics": ""}
    
    section_content = section_match.group(1)
    
    # 改进2：宽松匹配模板名称（允许任意数量空格/下划线）
    staff_pattern = r'\{\{VOCALOID(?:\s|_)+Songbox(?:\s|_)+Introduction(.*?)\}\}'
    staff_match = re.search(staff_pattern, section_content, re.DOTALL | re.IGNORECASE)
    
    staff_info = {}
    if staff_match:
        staff_content = staff_match.group(1)
        staff_info = parse_staff_info(staff_content)  # 使用新的解析函数
    
    # 歌词提取保持不变
    lyrics = ""
    poem_match = re.search(r'<poem[^>]*>([\s\S]*?)</poem>', section_content)
    if poem_match:
        lyrics_content = poem_match.group(1)
        lyrics = re.sub(r'\{\{color\|[^}|]+\|([^}]+)\}\}', r'\1', lyrics_content)
        lyrics = re.sub(r'\n{3,}', '\n\n', lyrics).strip()
    
    return {
        "staff": staff_info,
        "lyrics": lyrics
    }

def parse_staff_info(staff_content):
    """
    从VOCALOID Songbox模板内容中解析制作人员信息
    支持两种格式：
    1. group/list格式：|group1=角色 |list1=人员
    2. 直接键值对格式：|角色=人员
    
    Args:
        staff_content (str): 模板内容部分（不包含两边的{{}}）
    
    Returns:
        dict: 角色->人员的映射字典
    """
    # 统一匹配所有键值对
    kv_pattern = r'\|([^=]+?)\s*=\s*(.*?)\s*(?=\||\}\})'
    all_items = dict(re.findall(kv_pattern, staff_content, re.DOTALL))
    
    staff_info = {}
    
    # 判断是否使用group/list格式（检查是否存在group开头的键）
    use_group_format = any(k.startswith('group') for k in all_items)
    
    def clean_text(text):
        """清理维基标记的辅助函数"""
        text = re.sub(r'<br\s*/?>', '、', text)  # 替换换行符
        text = re.sub(r'\[\[(.*?)\]\]', r'\1', text)  # 移除维基链接标记
        text = re.sub(r'\{\{.*?\}\}', '', text)  # 移除模板标记
        return text.strip()
    
    if use_group_format:
        # 处理group/list格式
        group_keys = sorted(
            [k for k in all_items if k.startswith('group')],
            key=lambda x: int(x[5:]) if x[5:].isdigit() else 0
        )
        
        for group_key in group_keys:
            idx = group_key[5:]
            list_key = f"list{idx}"
            
            if list_key in all_items:
                role = clean_text(all_items[group_key])
                people = clean_text(all_items[list_key])
                if role and people:  # 忽略空值
                    staff_info[role] = people
    else:
        # 处理直接键值对格式
        ignore_keys = {'ldc', 'lbgcolor', 'ltcolor'}  # 要忽略的技术参数
        for key, value in all_items.items():
            key_lower = key.lower()
            if key_lower not in ignore_keys:
                role = clean_text(key)
                people = clean_text(value)
                if role and people:  # 忽略空值
                    staff_info[role] = people
    
    return staff_info


def parse_narrative_section(text):
    # 提取文案部分
    narrative = ""
    narrative_match = re.search(r'==\s*文案\s*==\s*<poem>([\s\S]*?)</poem>', text)
    
    if narrative_match:
        narrative_content = narrative_match.group(1)
        # 清理数字序号和多余空格
        narrative = re.sub(r'^\d+\s*', '', narrative_content, flags=re.MULTILINE)
        # 移除行首行尾空格
        narrative = '\n'.join(line.strip() for line in narrative.splitlines())
        # 移除多余空行
        narrative = re.sub(r'\n{3,}', '\n\n', narrative).strip()
    
    return narrative

def parse_staff_comments(text):
    """
    解析STAFF的话部分，提取所有Cquote模板中的内容
    :param text: MediaWiki格式的文本
    :return: 包含所有引用内容的列表，每个元素是一个字典
    """
    # 定位STAFF的话部分
    section_pattern = r'==\s*(STAFF的话|作者的话)\s*==\s*\n(.*?)(?=\n==|\Z)'
    section_match = re.search(section_pattern, text, re.DOTALL)
    
    if not section_match:
        return []
    
    section_content = section_match.group(1)
    
    # 匹配所有Cquote模板
    cquote_pattern = r'\{\{Cquote\|(.*?)\}\}'
    cquote_matches = re.findall(cquote_pattern, section_content, re.DOTALL)
    
    results = []
    
    for cquote_content in cquote_matches:
        # 提取内容部分（在<poem>标签内）
        poem_match = re.search(r'<poem>(.*?)</poem>', cquote_content, re.DOTALL)
        content = poem_match.group(1).strip() if poem_match else ""
        
        # 提取来源部分（在最后一个竖线之后）
        source_match = re.search(r'\|([^|]+)$', cquote_content)
        source = source_match.group(1).strip() if source_match else ""
        
        # 清理来源中的维基标记
        source = re.sub(r'\[\[|\]\]', '', source)
        
        results.append({
            "content": content,
            "source": source
        })
    
    return results
